home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 13500 < prev    next >
Encoding:
Text File  |  1996-08-05  |  5.3 KB  |  240 lines

  1. Path: taco.cc.ncsu.edu!news
  2. From: Scott Mebust <samebust@pop-in.ncsu.edu>
  3. Newsgroups: comp.lang.c++
  4. Subject: Embedded classes in Class Templates
  5. Date: 24 Mar 1996 18:53:20 GMT
  6. Organization: North Carolina State University
  7. Message-ID: <4j45n0$ck7@taco.cc.ncsu.edu>
  8. NNTP-Posting-Host: s013h011.dialup.ncsu.edu
  9. Mime-Version: 1.0
  10. Content-Type: text/plain; charset=us-ascii
  11. Content-Transfer-Encoding: 7bit
  12. X-Mailer: Mozilla 1.22 (Windows; U; 16bit)
  13.  
  14. RE:  Template Class Nested Types:  Private member functions of the
  15.      enclosing class that take parameters of the enclosed class type.
  16.  
  17.      (Damn the terminology!  Fool speed ahead!)
  18.  
  19.  
  20. I've got a question concerning "Template Class Nested Types" (as Lippman
  21. refers to them in his C++ Primer, 2nd Edition).  Trying my hand at
  22. creating some generic dynamic data types (container classes) in C++ using
  23. templates, I've had some success.  (I know, I know, with STL around, why
  24. should one bother?  A:  To learn.)  I've implemented the standard Stack
  25. and Queue, and they were both easy to "templatize".  In my Queue class
  26. template, I declared a Node class within the private section of the Queue
  27. class declaration.  This worked out well.  I have since coded a binary
  28. tree class with a similarly nested Node class.  The non-templatized
  29. version of this class compiled without error and worked well.  However,
  30. when I attempted to convert the class to a class template, I ran into a
  31. problem.  In a nutshell, some of the private member functions of the
  32. Binary Tree class take a reference to a pointer to a Node as a parameter.
  33. The declarations of these member functions cause no problems but the
  34. definitions of the member functions, which are outside of the class
  35. declaration, cause the compilers (GNU 2.7.0(?) under Linux,
  36. Borland C++ 3.1) to choke.  They apparently don't recognize the Node
  37. class (that is, it appears to be out of scope).  But, if I move the body
  38. of these member functions into the Binary Tree class declaration (inline),
  39. the compilers happily accept the code.  I have tried qualifying the
  40. Node class with the Tree class name and template parameter list but this
  41. didn't help (i.e. tree<type>::node ).
  42.  
  43. Q:  What limitation am I running up against?  What is my misunderstanding?
  44.  
  45. I've included "complete" code snippets below that demonstrate the problem.
  46. The first snippet is a non-template integer binary tree that compiles fine.
  47. The second snippet is a templatized binary tree class that bombs a couple
  48. of lines into the tree::Insert2 member function definition.  The third
  49. snippet is a templatized version in which I've moved the body of the
  50. tree::Insert2 member function into the tree template class declaration
  51. (inline).  The third snippet also compiles fine.
  52.  
  53. Thanks in advance for any help with this problem.  I've referenced
  54. Stroustrup, Lippman, and a couple of other books concerning this but to
  55. no avail.
  56.  
  57. // SNIPPET 1 //
  58.  
  59. #include <stddef.h>
  60.  
  61. class inttree
  62. {
  63.   public:
  64.     inttree();
  65.     void Insert(const int &i);
  66.     //
  67.     // other member functions like Delete, etc.
  68.     //
  69.  
  70.   private:
  71.     class node
  72.     {
  73.       public:
  74.         int value_;
  75.         node *lchild_, *rchild_;
  76.     };
  77.  
  78.     void Insert2(const int &i, node* &np);
  79.     //
  80.     // other private member functions
  81.     //
  82.  
  83.     node *root_;
  84. };
  85.  
  86.  
  87.  
  88. inttree::inttree()
  89. {
  90.   root_=NULL;
  91. }
  92.  
  93.  
  94. void inttree::Insert(const int &i)
  95. {
  96.   Insert2(i, root_);
  97. }
  98.  
  99.  
  100. void inttree::Insert2(const int &i, node* &np)
  101. {
  102.   if (np==NULL)
  103.   {
  104.     np=new node;
  105.     // assert (np!=NULL);
  106.     np->lchild_=NULL;
  107.     np->rchild_=NULL;
  108.     np->value_=i;
  109.   }
  110.   else if (i<np->value_)
  111.     Insert2 (i,np->lchild_);
  112.   else if (i>np->value_)
  113.     Insert2 (i,np->rchild_);
  114. }
  115.  
  116. // END SNIPPET 1 //
  117.  
  118. // SNIPPET 2 //
  119.  
  120. #include <stddef.h>
  121.  
  122. template <class info>
  123. class tree
  124. {
  125.   public:
  126.     tree();
  127.     void Insert(const info &i);
  128.     //
  129.     // other member functions like Delete, etc.
  130.     //
  131.  
  132.   private:
  133.     class node
  134.     {
  135.       public:
  136.         info value_;
  137.         node *lchild_, *rchild_;
  138.     };
  139.  
  140.     void Insert2(const info &i, node* &np);
  141.     //
  142.     // other private member functions
  143.     //
  144.  
  145.     node *root_;
  146. };
  147.  
  148.  
  149. template <class info>
  150. tree<info>::tree()
  151. {
  152.   root_=NULL;
  153. }
  154.  
  155. template <class info>
  156. void tree<info>::Insert(const info &i)
  157. {
  158.   Insert2(i, root_);
  159. }
  160.  
  161. template <class info>
  162. void tree<info>::Insert2(const info &i, node* &np)
  163. {
  164.   if (np==NULL)
  165.   {
  166.     np=new node;
  167.     // assert (np!=NULL);
  168.     np->lchild_=NULL;
  169.     np->rchild_=NULL;
  170.     np->value_=i;
  171.   }
  172.   else if (i<np->value_)
  173.     Insert2 (i,np->lchild_);
  174.   else if (i>np->value_)
  175.     Insert2 (i,np->rchild_);
  176. }
  177.  
  178. // END SNIPPET 2 //
  179.  
  180. // SNIPPET 3 //
  181.  
  182. #include <stddef.h>
  183.  
  184. template <class info>
  185. class tree
  186. {
  187.   public:
  188.     tree();
  189.     void Insert(const info &i);
  190.     //
  191.     // other member functions like Delete, etc.
  192.     //
  193.  
  194.   private:
  195.     class node
  196.     {
  197.       public:
  198.         info value_;
  199.         node *lchild_, *rchild_;
  200.     };
  201.  
  202.     void Insert2(const info &i, node* &np)
  203.     {
  204.       if (np==NULL)
  205.       {
  206.         np=new node;
  207.         // assert (np!=NULL);
  208.         np->lchild_=NULL;
  209.         np->rchild_=NULL;
  210.         np->value_=i;
  211.       }
  212.       else if (i<np->value_)
  213.         Insert2 (i,np->lchild_);
  214.       else if (i>np->value_)
  215.         Insert2 (i,np->rchild_);
  216.     }
  217.     //
  218.     // other private member functions
  219.     //
  220.  
  221.     node *root_;
  222. };
  223.  
  224.  
  225. template <class info>
  226. tree<info>::tree()
  227. {
  228.   root_=NULL;
  229. }
  230.  
  231. template <class info>
  232. void tree<info>::Insert(const info &i)
  233. {
  234.   Insert2(i, root_);
  235. }
  236.  
  237. // END SNIPPET 3 //
  238.  
  239.  
  240.